/* ========================================================================= */
/* ------------------------------------------------------------------------- */
/*!
  \file			tree3d.h
  \date			Dec 2011
  \author		TNick

  \brief		Contains the definition for Tree3D class


*//*

 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Please read COPYING and README files in root folder
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

*/
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
#ifndef __TREE3D_INC__
#define __TREE3D_INC__
//
//
//
//
/*  INCLUDES    ------------------------------------------------------------ */

/*  INCLUDES    ============================================================ */
//
//
//
//
/*  CLASS    --------------------------------------------------------------- */

class	Tree3DNode;

/**
*	@brief	that represents an element in a tree structure
*
*	This is a simple member in a tree structure. It is not allowed to have
*	kids of it's own and stores links to his siblings (previous() and next())
*	and to his father().
*
*	As Tree3DNode class inherits from this class, virtual function isNode()
*	is provided to be able to differentiate between nodes and leafs.
*
*
*/
class Tree3D				{

	//
	//
	//
	//
	/*  DEFINITIONS    ----------------------------------------------------- */

#ifndef	NULL
#define NULL	0
#endif

	friend class Tree3DNode;

#ifdef	OBJECTSLIB_TESTS
	friend void		Tree3D_Tests	( int&, int& );
#endif

	/*  DEFINITIONS    ===================================================== */
	//
	//
	//
	//
	/*  DATA    ------------------------------------------------------------ */

private:

	/**
	*	@brief	pointer to father node or NULL if this is top level
	*/
	Tree3DNode *		father_;

	/**
	*	@brief	pointer to next sibling or NULL if this is last in chain
	*/
	Tree3D *			next_;

	/**
	*	@brief	pointer to previous sibling or NULL if this is first one in chain
	*/
	Tree3D *			prev_;


	/*  DATA    ============================================================ */
	//
	//
	//
	//
	/*  FUNCTIONS    ------------------------------------------------------- */

public:

	Tree3D()	{ father_ = NULL; next_ = NULL; prev_ = NULL; }
	~Tree3D()	{ extract(); }

	/**
	*	@brief	tell if this is a node or an element
	*/
	virtual	bool			isNode			( void ) const
	{ return false; }


	/**
	*	@brief	return next item
	*/
	inline Tree3D*			next		( void ) const
	{ return next_; }


	/**
	*	@brief	return previous item
	*/
	inline Tree3D*			previous	( void ) const
	{ return prev_; }


	/**
	*	@brief	return parent item
	*/
	inline Tree3DNode*		father		( void ) const
	{ return father_; }



	/**
	*	@brief	get the index of this item inside it's father
	*/
	int						index		( void ) const;


	/**
	*	@brief	insert an item as sibling after this item
	*/
	void					insAfter	( Tree3D * new_node );


	/**
	*	@brief	insert an item as sibling before this item
	*/
	void					insBefore	( Tree3D * new_node );


	/**
	*	@brief	extract this item from the chain
	*/
	void					extract		( void );


	/**
	*	@brief	print the content of this item
	*/
	void					dbgDump		( void ) const;



protected:

	/**
	*	@brief	directly change next item ( no questions asked )
	*/
	inline void				setNext		( Tree3D * it_leaf )
	{ next_ = it_leaf; }

	/**
	*	@brief	directly change previous item ( no questions asked )
	*/
	inline void				setPrevious		( Tree3D * it_leaf )
	{ prev_ = it_leaf; }

	/**
	*	@brief	directly change father item ( no questions asked )
	*/
	inline void				setFather		( Tree3DNode * it_leaf )
	{ father_ = it_leaf; }



	/*  FUNCTIONS    ======================================================= */
	//
	//
	//
	//

};	/*	class Tree3D	*/


/*  CLASS    =============================================================== */
//
//
//
//
/*  CLASS    --------------------------------------------------------------- */

/**
*	@brief	that represents an node in a tree structure
*
*	Beside the elements that it inherits (previous(), next() and father()
*	the node also stores a link to first kid.
*
*	The class assumes that it's kids were allocated using new operator and
*	will attempt to delete them in destructor; to avoid this behaviour use
*	setFirstKid() with a NULL parameter.
*/
class Tree3DNode	: public Tree3D				{

	//
	//
	//
	//
	/*  DEFINITIONS    ----------------------------------------------------- */

#ifdef	OBJECTSLIB_TESTS
	friend void		Tree3D_Tests	( int&, int& );
#endif

	/*  DEFINITIONS    ===================================================== */
	//
	//
	//
	//
	/*  DATA    ------------------------------------------------------------ */

protected:

	/**
	*	@brief	pointer to first kid or NULL if this node has no kids
	*/
	Tree3D *			kid1_;


	/*  DATA    ============================================================ */
	//
	//
	//
	//
	/*  FUNCTIONS    ------------------------------------------------------- */

public:

	Tree3DNode():Tree3D()	{ kid1_ = NULL; }
	~Tree3DNode()			{ extract(); }



	/**
	*	@brief	tell if this is a node or an element
	*/
	virtual	bool		isNode			( void ) const
	{ return true; }


	/**
	*	@brief	return first direct child
	*/
	inline Tree3D*		firstKid		( void ) const
	{ return kid1_; }

	/**
	*	@brief	return last direct child
	*/
	Tree3D*				lastKid			( void ) const;


	/**
	*	@brief	return nth direct child
	*/
	Tree3D*				kid				( int nth ) const;


	/**
	*	@brief	return the number of kids for this item
	*/
	int					count			( void ) const;


	/**
	*	@brief	print the content of this item
	*/
	void				dbgDump			( void ) const;


	/**
	*	@brief	add a kid as last kid
	*/
	void				append			( Tree3D * it_leaf );


	/**
	*	@brief	add a kid as first kid
	*/
	void				prepend			( Tree3D * it_leaf );


	/**
	*	@brief	recursivelly deletes all the kids
	*
	*	This assumes that all the kids were allocated using the new opperator
	*/
	void				clear			( void );


protected:

	/**
	*	@brief	directly change first kid ( no questions asked )
	*/
	inline void			setFirstKid		( Tree3D * it_leaf )
	{ kid1_ = it_leaf; }


	/*  FUNCTIONS    ======================================================= */
	//
	//
	//
	//

};	/*	class Tree3DNode	*/


/*  CLASS    =============================================================== */
//
//
//
//

#ifdef	OBJECTSLIB_TESTS
void				Tree3D_Tests					(
		int & performed, int & succeded );
#endif

#endif // __TREE3D_INC__
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
